package sebastiankerckhof.structure;

import sebastiankerckhof.render.raytrace.Hit;
import sebastiankerckhof.render.raytrace.Ray;




public class Triangle{
	public Edge[] nbr = new Edge[3];
	public Vertex a;
	public Vertex b;
	public Vertex c;
	
	public Triangle(){}
	
	public Triangle(Vertex a, Vertex b, Vertex c){
		this.a = a;
		this.b = b;
		this.c = c;
	}
	
	public Triangle(Vertex[] v){
		this.a = v[0];
		this.b = v[1];
		this.c = v[2];
	}
	
	public int xMin(){
		float val;
		if(a.position.x < b.position.x && a.position.x < c.position.x)
			val = a.position.x;
		else if(b.position.x < c.position.x)
			val = b.position.x;
		else
			val = c.position.x;
		
		return (int) Math.floor(val);
	}
	
	public int xMax(){
		float val;
		if(a.position.x > b.position.x && a.position.x > c.position.x)
			val =  a.position.x;
		else if(b.position.x > c.position.x)
			val = b.position.x;
		else
			val = c.position.x;
		
		return (int) Math.ceil(val);
	}
	
	public int yMin(){
		float val;
		if(a.position.y < b.position.y && a.position.y < c.position.y)
			val = a.position.y;
		else if(b.position.y < c.position.y)
			val = b.position.y;
		else
			val = c.position.y;
		
		return (int) Math.floor(val);
	}
	
	public int yMax(){
		float val;
		if(a.position.y > b.position.y && a.position.y > c.position.y)
			val = a.position.y;
		else if(b.position.y > c.position.y)
			val = b.position.y;
		else
			val = c.position.y;
		
		return (int) Math.ceil(val);
	}

  public boolean intersect(Ray r, float t0, Hit hr){
  	//TODO: reuse of numbers
  	
  	//all vars marked with * depend on the ray;
  	
  	float a = this.a.position.x - this.b.position.x;
  	float b = this.a.position.y - this.b.position.y;
  	float c = this.a.position.z - this.b.position.z;
  	
  	float d = this.a.position.x - this.c.position.x;
  	float e = this.a.position.y - this.c.position.y;
  	float f = this.a.position.z - this.c.position.z;
  	
  	float g = r.direction.x;//*
  	float h = r.direction.y;//*
  	float i = r.direction.z;//*
  	
  	float j = this.a.position.x - r.origin.x;//*
  	float k = this.a.position.y - r.origin.y;//*
  	float l = this.a.position.z - r.origin.z;//*
  	
  	float ei_minus_hf = e*i - h*f; //*
  	float gf_minus_di = g*f - d*i; //*
  	float dh_minus_eg = d*h - e*g; //*
  	
  	float ak_minus_jb = a*k - j*b; //*
  	float jc_minus_al = j*c - a*l; //*
  	float bl_minus_kc = b*l - k*c; //*
  	
  	float M = a*ei_minus_hf + b*gf_minus_di +c*dh_minus_eg;
  	
  	float t = ( f*ak_minus_jb + e*jc_minus_al + d*bl_minus_kc) / M;
  
  	
  	if(t < 0 || t > hr.distance)
  		return false;
  	

  	
  	float gamma = (i*ak_minus_jb + h*jc_minus_al + g*bl_minus_kc) / M;
  	if(gamma < 0 || gamma > 1)
  		return false;
  	
  	float beta = (j*ei_minus_hf + k*gf_minus_di + l*dh_minus_eg) / M;
  	if(beta < 0 || beta > (1-gamma))
  		return false;
  	
  	hr.distance = t;
  	
  	//TODO: check this normal
  	hr.normal = this.a.normal.scale(1.0f-beta-gamma).add(
  					this.b.normal.scale(beta).add(
  							this.c.normal.scale(gamma)));
  	hr.normal = hr.normal.normal();
  			
  	return true;
  	
  }



}
